package com.yneusoft.manage.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yneusoft.common.model.ResponseWrapper;
import com.yneusoft.common.tool.CommonTool;
import com.yneusoft.dao.entity.Department;
import com.yneusoft.dao.entity.DepartmentStaff;
import com.yneusoft.dao.entity.DepartmentState;
import com.yneusoft.dao.mapper.DepartmentMapper;
import com.yneusoft.dao.mapper.DepartmentStaffMapper;
import com.yneusoft.manage.mapper.DepartmentManageMapper;
import com.yneusoft.manage.model.param.*;
import com.yneusoft.manage.model.result.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;

/**
 * 部门管理 service
 */
@Slf4j
@Service
public class DepartmentManageService {
    @Resource
    DepartmentManageMapper departmentManager;

    @Resource
    DepartmentMapper departmentMapper;

    @Resource
    DepartmentStaffMapper departmentStaffMapper;



    /**
     * 启用/禁用部门
     * @param  param 部门aid
     * @return true(修改状态成功)，false(修改状态失败)
     */
    @Transactional
    public ResponseWrapper isDepartment(UpdateDepartmentStateParam param){
        LambdaUpdateWrapper<Department> wrap= new LambdaUpdateWrapper<>();
        wrap.eq(Department::getAid,param.getAid()).set(Department::getStateId,param.getStateId()).set(Department::getStateName,param.getStateName());
        int i = departmentMapper.update(null, wrap);
        if (i>0){
            return ResponseWrapper.markSuccess();
        }else
            return ResponseWrapper.markError();
    }

    /**
     * 获取部门状态列表
     * @return 部门状态的所有情况
     */
    public ResponseWrapper getDepartmentState(){
        List<GetDepartmentStateListResult> result= JSONArray.parseArray(JSON.toJSONString(DepartmentState.dataList
        )).toJavaList(GetDepartmentStateListResult.class);
        return ResponseWrapper.markSuccess(result);
    }


    /**
     * 【新增/修改】获取部门状态列表
     * @return 部门状态的所有情况
     */
    public ResponseWrapper getDepartmentStateList(){
        List<GetDepartmentStateListResult> result= JSONArray.parseArray(JSON.toJSONString(DepartmentState.dataList
        )).toJavaList(GetDepartmentStateListResult.class);
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 【新增/修改】获取修改部门列表
     * @param  param 部门aid
     * @return 部门list
     */
    public ResponseWrapper getDepartmentInfo(UpdateDepartmentListParam param){
        List<Map<String, Object>> departmentInfo = departmentManager.getDepartmentInfo(param.getAid());
        if (departmentInfo.size()>0){
            List<DepartmentInfoResult> departmentInfoResults = CommonTool.mapListToBeanList(departmentInfo, DepartmentInfoResult.class);
            return ResponseWrapper.markSuccess(departmentInfoResults);
        }else
            return ResponseWrapper.markError();

    }

    /**
     * 获取部门信息列表
     * @param param 部门aid
     * @return 部门aid,部门名称
     */
    public ResponseWrapper getDepartmentNameList(GetDepartmentNameListParam param){
        LambdaQueryWrapper<Department> wrapper=new LambdaQueryWrapper<>();
        if (param.getAid() == null){
            wrapper.select(Department::getAid,Department::getName);
            List<Department> list= departmentMapper.selectList(wrapper);
            List<GetDepartmentNameListResult> result=JSONArray.parseArray(JSON.toJSONString(list)).toJavaList(GetDepartmentNameListResult.class);
            return ResponseWrapper.markSuccess(result);
        }else {
            wrapper.select(Department::getAid,Department::getName).ne(Department::getAid,param.getAid());
        }
        List<Department> list= departmentMapper.selectList(wrapper);
        List<GetDepartmentNameListResult> result=JSONArray.parseArray(JSON.toJSONString(list)).toJavaList(GetDepartmentNameListResult.class);
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 【新增/修改】校验同名的其他部门
     * @return true(存在同名部门)，false(不存在同名部门)
     */
    public ResponseWrapper checkDepartmentName(CheckDepartmentNameParam param){
        CheckDepartmentNameResult checkDepartmentName = new CheckDepartmentNameResult();
        if (param.getAid()==null){
            List<Map<String, Object>> departmentInfo1 = departmentManager.getDepartmentInfo1(param.getName());
            if (departmentInfo1.size() > 0){
                List<DepartmentInfoResult> getDepartmentNameLists = CommonTool.mapListToBeanList(departmentInfo1, DepartmentInfoResult.class);
                checkDepartmentName.setDepartmentInfoResult(getDepartmentNameLists);
                checkDepartmentName.setIsExists(true);
                return ResponseWrapper.markCustomSuccess("新增名称存在",checkDepartmentName);
            }else {
                checkDepartmentName.setIsExists(false);
                checkDepartmentName.setDepartmentInfoResult(null);
                return ResponseWrapper.markCustomSuccess("新增名称不存在",checkDepartmentName);
            }
        }else {
            List<Map<String, Object>> departmentInfo2 = departmentManager.getDepartmentInfo2(param.getAid(), param.getName());
            if (departmentInfo2.size() > 0){
                List<DepartmentInfoResult> getDepartmentNameLists = CommonTool.mapListToBeanList(departmentInfo2, DepartmentInfoResult.class);
                checkDepartmentName.setIsExists(true);
                checkDepartmentName.setDepartmentInfoResult(getDepartmentNameLists);
                return ResponseWrapper.markCustomSuccess("修改名称存在",checkDepartmentName);
            }else {
                checkDepartmentName.setIsExists(false);
                checkDepartmentName.setDepartmentInfoResult(null);
                return ResponseWrapper.markCustomSuccess("修改名称不存在",checkDepartmentName);
            }
        }
    }

    /**
     * 删除部门
     * @param param 部门aid
     * @return 是否删除
     */
    @Transactional
    public ResponseWrapper deleteDepartment(DeleteDepartmentParam param){
        LambdaQueryWrapper<DepartmentStaff> lambdaQueryWrap = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Department> lambdaQueryWrap1 = new LambdaQueryWrapper<>();
        if (param.getAid() != null){
            lambdaQueryWrap.eq(DepartmentStaff::getDepartmentAid,param.getAid()).groupBy(DepartmentStaff::getDepartmentAid);
            Integer count = departmentStaffMapper.selectCount(lambdaQueryWrap);
            lambdaQueryWrap1.eq(Department::getFatherAid,param.getAid());
            List<Department> list = departmentMapper.selectList(lambdaQueryWrap1);
            if (count!=null||list.size() > 0){
                return ResponseWrapper.markCustomError("部门下有子部门或者部门有员工，不能删除");
            }else{
                LambdaQueryWrapper<Department> wrapper=new LambdaQueryWrapper<>();
                wrapper.eq(Department::getAid,param.getAid());
                int i = departmentMapper.delete(wrapper);
                if (i>0){
                    return ResponseWrapper.markCustomSuccess("删除成功");
                }else
                    return ResponseWrapper.markCustomError("删除失败");
            }
        }else
            return ResponseWrapper.markError();
    }

    /**
     * 检验父部门是否是其子孙分类
     * @return true(父部门是其子孙分类),false(父部门不是其子孙分类)
     */
    public ResponseWrapper checkFatherDepartment(CheckFatherDepartmentParam param){
        return ResponseWrapper.markSuccess(this.checkFatherDepartmentName(param.getAid(), param.getFatherAid()));
    }


    /**
     * 得到部门列表
     * @return 部门tree
     */
    public ResponseWrapper getDepartmentTree(DepartmentTreeParam param){
        List<DepartmentTreeNodeResult> list=new ArrayList<>();
        DepartmentTreeResult result=new DepartmentTreeResult();
        LambdaQueryWrapper<Department> wrap=new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(param.getSearchKey())||param.getId()!=null){
            wrap.like(param.getSearchKey()!=null,Department::getName,param.getSearchKey())
                    .eq(param.getId()!=null,Department::getStateId,param.getId());
        }else {
            wrap.isNull(Department::getFatherAid);
        }

        Page<Department> page=new Page<>(param.getPage(),param.getPageSize());
        IPage<Department> iPage=departmentMapper.selectPage(page,wrap);
        log.info("-------->"+iPage.getSize());
        log.info("---->"+iPage.getTotal());
        List<Integer> list1=new ArrayList<>();
        for (Department depart: iPage.getRecords()) {

            DepartmentTreeNodeResult tree = new DepartmentTreeNodeResult();
            tree.setAid(depart.getAid());
            list1.addAll(getChildAid(depart.getAid()));
            tree.setName(depart.getName());
            tree.setCode(depart.getCode());
            tree.setNumber(staffNum(getChildAid(depart.getAid())));
            tree.setIsEnable(depart.getStateId() == 1);
            tree.setIsDelete(staffNum(getChildAid(depart.getAid()))==0||getChildAid(depart.getAid()).size()==0);
            tree.setCreateTime(depart.getCreateTime());
            if (StringUtils.isNotBlank(param.getSearchKey())||param.getId()!=null){
                tree.setChildren(null);
            }else {
                tree.setChildren(getChildNode(depart));
            }

            list.add(tree);
        }
        list1= new ArrayList<>(new LinkedHashSet<>(list1));
        result.setDepartmentNumbers(list1.size());
        result.setRowNumber((int) iPage.getTotal());
        result.setDepartmentList(list);
        return ResponseWrapper.markSuccess(result);
    }


    /**
     * 保存新增/修改部门
     * @param param 新增/修改部门实体类
     * @return 成功/失败
     */
    @Transactional
    public ResponseWrapper saveDepartment(SaveDepartmentParam param){
        Department department=new Department();
        LambdaQueryWrapper<Department> wrap=new LambdaQueryWrapper<>();
        wrap.eq(Department::getAid,param.getFatherAid());
        List<Department> list = departmentMapper.selectList(wrap);
        List<Integer> list1=new ArrayList<>();

        if (param.getAid()==null){
            department.setCode(param.getDepartmentCode());
            department.setName(param.getName());
            department.setStateId(param.getId());
            department.setStateName(param.getStateName());
            department.setFatherAid(param.getFatherAid());
            if (param.getFatherAid()==null){
                department.setLevel(0);
            }else {
                for (Department department1 : list) {
                    list1.add(department1.getLevel());
                }
                list1=new ArrayList<>(new LinkedHashSet<>(list1));
                department.setLevel(list1.get(0)+1);
            }

            int insert = departmentMapper.insert(department);
            if (insert > 0) {
                return ResponseWrapper.markSuccess("添加成功");
            }else
                return ResponseWrapper.markCustomError("添加失败");
        }else {
            LambdaUpdateWrapper<Department> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(Department::getAid,param.getAid()).set(Department ::getName,param.getName())
                    .set(Department::getStateId,param.getId()).set(Department::getStateName,param.getStateName()).set(Department::getFatherAid,param.getFatherAid());
            if (param.getFatherAid()==null){
                wrapper.set(Department::getLevel,0);
            }else {
                for (Department department1 : list) {
                    list1.add(department1.getLevel());
                }
                list1=new ArrayList<>(new LinkedHashSet<>(list1));
                wrapper.set(Department::getLevel,list1.get(0)+1);
            }

            int update = departmentMapper.update(null, wrapper);
            if (update > 0) {
                return ResponseWrapper.markSuccess("修改成功");
            }else
                return ResponseWrapper.markCustomError("修改失败");
        }
    }


    /**
     * 处理检验父部门是否是其子孙分类的方法
     * @param aid 部门aid
     * @param fatherAid 部门的父部门aid
     * @return true,false
     */
    public boolean checkFatherDepartmentName(Integer aid,Integer fatherAid){
        List<Map<String,Object>> lis=departmentManager.getDepartmentChildren(aid);
        for (Map<String,Object> map:lis){
            if (( map.get("aid"))==fatherAid){
                return true;
            }
            else {
                checkFatherDepartmentName((Integer) map.get("aid"),fatherAid);
            }
        }
        return false;
    }


    /**
     * 获取子列表
     * @param department 部门实体
     * @return 子列表
     */
    public List<DepartmentTreeNodeResult> getChildNode(Department department){
        List<DepartmentTreeNodeResult> list1=new ArrayList<>();
        LambdaQueryWrapper<Department> wrap=new LambdaQueryWrapper<>();
        wrap.eq(Department::getFatherAid,department.getAid());
        List<Department> list = departmentMapper.selectList(wrap);
        if (list.size() > 0) {
            for (Department department1 : list) {
                DepartmentTreeNodeResult treeNode = new DepartmentTreeNodeResult();
                treeNode.setAid(department1.getAid());
                treeNode.setName(department1.getName());
                treeNode.setCode(department1.getCode());
                treeNode.setNumber(staffNum(getChildAid(department1.getAid())));
                treeNode.setIsEnable(department1.getStateId()==1);
                treeNode.setIsDelete(staffNum(getChildAid(department1.getAid()))==0||getChildAid(department1.getAid()).size()==0);
                treeNode.setCreateTime(department1.getCreateTime());
                treeNode.setChildren(getChildNode(department1));
                list1.add(treeNode);
            }

        }
        return list1;
    }


    /**
     * 获取子孙aid
     * @param aid 部门aid
     * @return list<Integer>
     */
    public List<Integer> getChildAid(Integer aid){
        LambdaQueryWrapper<Department> wrap=new LambdaQueryWrapper<>();
        List<Integer> list1=new ArrayList<>();
        wrap.eq(Department::getFatherAid,aid);
        List<Department> list = departmentMapper.selectList(wrap);
        if (list.size() > 0) {
            for (Department department : list) {
                list1.add(department.getAid());
                list1.add(aid);
                List<Integer> list2=getChildAid(department.getAid());
                list1.addAll(list2);
            }
        }else {
            list1.add(aid);
        }
        return list1;
    }

    /**
     * 获取自己以及子孙的总人数
     * @param list aid列表
     * @return 子部门以及子孙部门人数之和
     */
    public Integer staffNum(List<Integer> list){
        Integer sum=0;
        list= new ArrayList<>(new LinkedHashSet<>(list));
        LambdaQueryWrapper<DepartmentStaff> wrap;

        for (Integer i : list) {
            wrap=new LambdaQueryWrapper<>();
            wrap.eq(DepartmentStaff::getDepartmentAid,i).groupBy(DepartmentStaff::getDepartmentAid);
            if(departmentStaffMapper.selectCount(wrap)!=null){
                sum+=departmentStaffMapper.selectCount(wrap);
            }
        }
        return sum;
    }

}
